package com.ywd.platform.websocket.session;

import cn.hutool.core.collection.CollUtil;
import com.ywd.platform.context.WebSocketContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * WebSocket 会话管理器
 * 负责维护所有活跃的WebSocket连接，支持用户多设备同时在线管理
 * 采用线程安全的ConcurrentHashMap结构，Key为用户ID，Value为该用户的所有会话
 */
@Slf4j
@Component
public class WebSocketSessionManager {
    /**
     * 用户会话存储结构：
     * - 外层Key: 用户ID (Long)
     * - 内层Key: WebSocket会话ID (String)
     * - 值: WebSocketSession对象
     */
    private final ConcurrentMap<Long, ConcurrentMap<String, WebSocketSession>> userSessions =
            new ConcurrentHashMap<>();

    /**
     * 添加用户会话
     *
     * @param session 待添加的WebSocket会话对象
     */
    public void addSession(WebSocketSession session) {
        // 从上下文获取用户ID（需在握手阶段通过拦截器设置）
        Long userId = WebSocketContext.getUserId();
        if (userId == null) {
            log.warn("Add session failed: missing user ID in session {}", session.getId());
            return;
        }
        // 原子操作：如果用户ID不存在则创建新的内层Map，然后添加会话
        userSessions.computeIfAbsent(userId, k -> new ConcurrentHashMap<>())
                .putIfAbsent(session.getId(), session);

        log.debug("Session added: user={}, session={}", userId, session.getId());
    }

    /**
     * 移除用户会话
     *
     * @param session 待移除的WebSocket会话对象
     */
    public void removeSession(WebSocketSession session) {
        Long userId = WebSocketContext.getUserId();
        if (userId == null) {
            log.warn("Remove session failed: missing user ID in session {}", session.getId());
            return;
        }
        // 原子操作：移除指定会话，如果用户会话列表为空则清除用户条目
        userSessions.computeIfPresent(userId, (k, sessionMap) -> {
            sessionMap.remove(session.getId());
            log.debug("Session removed: user={}, session={}", userId, session.getId());
            return sessionMap.isEmpty() ? null : sessionMap;  // 返回null会删除外层Key
        });
    }

    /**
     * 获取用户的所有活跃会话
     *
     * @param userId 目标用户ID
     * @return 该用户的会话列表（无会话时返回空列表，非null）
     */
    public List<WebSocketSession> getSessionList(Long userId) {
        // 获取用户会话映射表
        ConcurrentMap<String, WebSocketSession> sessionMap = userSessions.get(userId);
        // 使用CollUtil.isEmpty判断（需引入hutool工具包或替换为原生判断）
        if (CollUtil.isEmpty(sessionMap)) {
            log.debug("No active sessions for user {}", userId);
            return Collections.emptyList();  // 返回不可变空列表节省内存
        }
        // 返回会话副本避免外部修改影响内部数据
        return new ArrayList<>(sessionMap.values());
    }

    // ====== 可选增强功能 ======
    /**
     * 获取当前在线用户数
     */
    public int getOnlineUserCount() {
        return userSessions.size();
    }
    /**
     * 获取当前总连接数
     */
    public int getTotalConnectionCount() {
        return userSessions.values().stream()
                .mapToInt(Map::size)
                .sum();
    }

}